iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 11
2
Mobile Development

iOS Developer Learning Flutter系列 第 11

iOS Developer Learning Flutter. Lesson10 建立列表

  • 分享至 

  • xImage
  •  

ListView有兩種用法
使用children 跟 使用builder
使用children就是會一次事先把所有widget都create出來
使用builder則是滾動到該widget時才create
我個人是把它類比成iOS的UITableView static/dynamic cell
或Android的listView/RecycleView

超級比一比(雖然本質相同, 但小地方差異還真不少...?)

  1. 雖然有個跟UITableViewCell類似的東東:ListTile(磚塊)☘️☘️☘️
    但並不會強制ListView只能放ListTile⚠️⚠️⚠️
    這就提升了UI的靈活度
    不會有TableView要改CollectionView, cell也要跟著改的問題= =
  2. 以前TableView只能直的, 但現在只要指定scrollDirection: Axis.horizontal就變橫了⚠️⚠️⚠️
  3. scrollbar不再只是一個bool了, 而是一個容器元件⚠️⚠️⚠️
    如果listView想要有scrollbar就要被Scrollbar包起來(繞口令)
  4. separator也不再是一個屬性了⚠️⚠️⚠️
    如果要自動產生分隔線
    就必須使用ListView.separated
    用法跟等等會提到的ListView.builder幾乎一樣
    只是要多給一個separatorBuilder
  5. 點擊事件(onTap)改由ListTile自己處理了⚠️⚠️⚠️
    如果是null的話, 一樣會讓點擊失效
  6. 多了一個scrollController⚠️⚠️⚠️, 透過它才能控制及監聽scroll
  7. shrinkWrap屬性我還以為是可以做到以前tableFooterView = UIView()的效果...⚠️⚠️⚠️
    結果只是控制scroll範圍
    (還好就算用了ListView.separated也不會在空白處多畫線)
  8. reverse屬性可以讓資料反過來長⚠️⚠️⚠️
    也就是由下往上出現(超酷的= =)
    所以資料比較少的時候是上方會留白
    (想當年面試還被問到怎麼用TableView實現...而且是面試者真的被客戶要求做出來XDD)

1. ListView using children

這種的ListView就可以當作SingleChildScrollView + Column
下圖顯示了ListTile不同狀態顯示的樣子(如果是disable就不能被tap)
除了onTap, 還提供了onLongPress call back

2. ListView using builder


至於ListView用法簡潔了很多, 直接看code吧

//主要的部分就這樣, 沒了
    final list = ListView.builder(
        controller: listViewController,
        //itemExtent: 44, //如果指定高度, null的話就自適應
        itemCount: messages.length, //numberOfRowsInSection
        itemBuilder: (ctx, idx) { //cellForRowAt
          return MessageTile("${messages[idx]}");
        }
    )
    
//輸入的部分
TextField(
  controller: textFieldController,
  decoration: InputDecoration(
    labelText: '有什麼話想說?',
    prefixIcon: Icon(Icons.message),
  ),
  onSubmitted: (text) { //送出訊息後, 透過listViewController定位至最新一筆
    setState(() {
      if (text.length > 0) {
        messages.add(text);
      }
     listViewController.jumpTo(listViewController.position.maxScrollExtent);
    });
  },
)

//訊息widget的layout 使用兩層cell一層, label一層
Container(
  padding: EdgeInsets.all(8), //cell邊距(就是圖片邊距)
  alignment: Alignment.centerRight,  //user視角的訊息是靠右的
  child: ConstrainedBox(
    constraints: BoxConstraints(maxWidth: 200), //限制寬度, 超過折行
    child: Container(
      padding: EdgeInsets.fromLTRB(24, 16, 32, 16),  //label邊距, 讓圖片包起來
      child: Text(message, //文字訊息預設靠左
        style: TextStyle(color: Colors.white),
      ),
      decoration: BoxDecoration( //給個底圖
        image: DecorationImage(
          image: AssetImage("resource/images/bubble_full_tail.png"),
          fit: BoxFit.fill
        )
      )
    )
  )
)

3. 對照表

Android iOS Flutter
ListView UITableView static cell ListView use children
RecycleView UITableView dynamic cell ListView.builder

參考連結


本集內容Android版請見:iOS Developer Learning Android. Lesson 16

下集預告:還是列表

最後提供一下github.com/mark33699/IDLF


上一篇
iOS Developer Learning Flutter. Lesson9 選擇器
下一篇
iOS Developer Learning Flutter. Lesson11 又是列表(置頂與刷新)
系列文
iOS Developer Learning Flutter30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言